package com.wk.jetpackdemo.ui.main

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.support.v4.app.Fragment
import android.support.v7.util.DiffUtil
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.wk.jetpackdemo.R
import com.wk.jetpackdemo.db.AppDatabase
import com.wk.jetpackdemo.db.entities.Book
import com.wk.jetpackdemo.db.entities.BookUser
import com.wk.jetpackdemo.db.entities.Loan
import com.wk.jetpackdemo.db.entities.User
import com.wk.jetpackdemo.utils.CommonUtils
import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * 1. 删除的时候传入的bean只要传入主键即可，如果不传入主键删除会失败！->@Delete
 * 2. @Query注解的方法可以用来执行任何的语句：SELECT/UPDATE/DELETE
 */
class MainFragment : Fragment(), View.OnClickListener {

    private var recyclerView: RecyclerView? = null

    var index = -1
    override fun onClick(v: View?) {
        v ?: return
        when (v.id) {
            R.id.add -> {
                if (index == -1) {
                    Toast.makeText(activity!!, "数据尚未初始化，请稍候重试！", Toast.LENGTH_LONG).show()
                    return
                }
                val user = User()
                user.userId = index
                index++
                user.gender = index % 2
                user.userName = "Jack$index"
                user.age = index
                val list = ArrayList<User>()
                list.add(user)
                executeDbCmd(Runnable {
                    AppDatabase.Holder.INSTANCE.testUserDao.insert(list)
                })
            }
            R.id.delete -> {
                val user = User()
                user.userId = index - 1
                executeDbCmd(Runnable {
                    // 删除的时候传入的bean只要传入主键即可，如果不传入主键删除会失败！
                    AppDatabase.Holder.INSTANCE.testUserDao.deleteItem(user)
                })
            }
        }


    }

    private fun executeDbCmd(runnable: Runnable) {
        executors.execute(runnable)
    }

    companion object {
        fun newInstance() = MainFragment()
        const val TAG = "MainFragment"
    }

    private val handler: Handler = Handler(Looper.getMainLooper())
    override fun onPause() {
        super.onPause()
        handler.postDelayed({
            for (i in 0..2) {
                onClick(null)
            }
        }, 1000)
    }

    private lateinit var viewModel: MainViewModel

    private val executors: ExecutorService = Executors.newFixedThreadPool(1)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.main_fragment, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView(view)
        testKotlinSyntax()
    }

    private fun testKotlinSyntax() {
        // T.also/T.apply--->返回的都是调用对象，而不是最后一行的对象--->前者通过it调用，后者是this
        // T.run/T.let返回的都是最后一行的对象--->前者通过this后者通过it调用
        val user = User()
        user.run {
            Log.e(TAG,"first run:$this")
            userName = "Hello"
            userId = 1000
            age = 10
            this
        }.run {
            Log.e(TAG,"second run:$this")
        }

        user.also {

        }.also {

        }

        user.let {
            user
        }.let {

        }

        user.apply {

        }.apply {

        }
    }

    private fun initView(view: View) {
        view.findViewById<Button>(R.id.add).setOnClickListener(this)
        view.findViewById<Button>(R.id.delete).setOnClickListener(this)
        recyclerView = view.findViewById(R.id.recycler)
        val layoutManager = LinearLayoutManager(activity)
        recyclerView?.layoutManager = layoutManager
        adapter = Adapter()
        recyclerView?.adapter = adapter
    }

    private var adapter: Adapter? = null
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        activity ?: return
        viewModel = ViewModelProviders.of(activity!!).get(MainViewModel::class.java)
        viewModel.getUsers().observe(this, Observer<List<User>> {
            if (it == null || it.isEmpty()) {
                Log.e(TAG, "data is null")
                index = 0
                return@Observer
            }
//            it.forEach { user ->
//                Log.e(TAG, "user:$user")
//            }
            adapter?.setData(it)
            index = it.last().userId + 1
        })

        executeDbCmd(Runnable {
            val bookUser = BookUser()
            bookUser.age = 100
            bookUser.id = "1"
            bookUser.lastName = "Bush"
            bookUser.name = "Tom"

            val book = Book()
            book.id = "101"
            book.title = "xiyouji"

            val loan = Loan()
            loan.bookId = "101"
            loan.userId = "1"
            loan.id = "11"
            val date = Date()
            loan.startTime = Date(date.year, date.month, date.date, date.hours - 1, date.minutes)
            loan.endTime = date

            val insertBook = AppDatabase.Holder.INSTANCE.bookDao.insertBook(book)
            val insertUser = AppDatabase.Holder.INSTANCE.bookDao.insertUser(bookUser)
            val insertLoan = AppDatabase.Holder.INSTANCE.bookDao.insertLoan(loan)
            Log.e(TAG, "book:$insertBook  user:$insertUser  loan:$insertLoan")

//            loan.id = "22"
//            loan.userId = "22"
//            AppDatabase.Holder.INSTANCE.bookDao.insertLoan(loan)
        })
    }

    private inner class Adapter : RecyclerView.Adapter<Adapter.Holder>() {
        private var users: List<User>? = null
        private val diffUtil: Diff = Diff()
        fun setData(users: List<User>?) {
            CommonUtils.runOnUiThread(Runnable {
                diffUtil.calculateDiffs(this.users, users)
                val result = DiffUtil.calculateDiff(diffUtil)
                result.dispatchUpdatesTo(this)
                this.users = users
            })


        }

        override fun onCreateViewHolder(p0: ViewGroup, p1: Int): Holder {
            return Holder(LayoutInflater.from(p0.context).inflate(R.layout.item_user, p0, false))
        }

        override fun getItemCount(): Int {
            return users?.size ?: 0
        }

        override fun onBindViewHolder(p0: Holder, p1: Int) {
            Log.e(TAG, "onBindViewHolder:$p1")
            val user = users!![p1]
            val stringBuilder = StringBuilder()
            stringBuilder.append("userId:")
            stringBuilder.append(user.userId)
            stringBuilder.append("\ngender:")
            stringBuilder.append(when {
                user.gender == User.GENDER.MALE.ordinal -> "男性"
                user.gender == User.GENDER.FEMALE.ordinal -> "女性"
                else -> "未知"
            })
            stringBuilder.append("\nuserName:")
            stringBuilder.append(user.userName)
            stringBuilder.append(" and age is:")
            stringBuilder.append(user.age)
            p0.text?.text = stringBuilder.toString()
        }

        inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnLongClickListener {
            override fun onLongClick(v: View?): Boolean {
                val adapterPosition = adapterPosition
                val user = users?.get(adapterPosition)
                user ?: return true
                executeDbCmd(Runnable {
                    // 删除失败，如果bean中不包含主键，则删除会失败
//                    val user_ = User()
//                    user_.userName = user.userName
//                    AppDatabase.Holder.INSTANCE.userDao.deleteItem(user)
                    AppDatabase.Holder.INSTANCE.testUserDao.updateAge(user.userId, user.age + 100)
                })
                return true
            }

            var text: TextView? = null

            init {
                text = itemView.findViewById(R.id.text)
                itemView.setOnLongClickListener(this)
            }

        }

    }

    private inner class Diff : DiffUtil.Callback() {
        private var oldUsers: List<User>? = null
        private var newUsers: List<User>? = null
        fun calculateDiffs(oldUsers: List<User>?, newUsers: List<User>?) {
            this.oldUsers = oldUsers
            this.newUsers = newUsers
        }

        override fun areItemsTheSame(p0: Int, p1: Int): Boolean {
            val old = oldUsers?.get(p0)
            val new = newUsers?.get(p1)
            return Objects.equals(old?.userId, new?.userId)
        }

        override fun getOldListSize(): Int {
            return oldUsers?.size ?: 0
        }

        override fun getNewListSize(): Int {
            return newUsers?.size ?: 0
        }

        override fun areContentsTheSame(p0: Int, p1: Int): Boolean {
            val oldUser = oldUsers?.get(p0)
            val newUser = newUsers?.get(p1)
            return oldUser?.equals(newUser) ?: (newUser == null)
        }

    }
}

